package com.hang.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hang.entity.Department;
import com.hang.entity.Dict;
import com.hang.entity.Role;
import com.hang.entity.User;
import com.hang.exception.MyException;
import com.hang.exception.MyExceptionEnum;
import com.hang.mapper.DepartmentMapper;
import com.hang.mapper.RoleMapper;
import com.hang.mapstruct.UserMapStruct;
import com.hang.model.dto.request.PasswordDTO;
import com.hang.model.dto.request.UserInfoDTO;
import com.hang.model.dto.request.UserInfoRegisterDTO;
import com.hang.model.dto.request.UserQueryModelReq;
import com.hang.model.dto.response.DictDTO;
import com.hang.model.vo.UserInfoDetailVO;
import com.hang.model.vo.UserInfoVO;
import com.hang.service.IUserService;
import com.hang.mapper.UserMapper;
import com.hang.util.MD5;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 *
 */
@Service
@AllArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
    implements IUserService{
    private UserMapStruct userMapStruct;

    private RoleMapper roleMapper;

    private DepartmentMapper departmentMapper;

    /**
     * 注册新用户
     *
     * @return
     */
    @Override
    public Boolean registerUser(UserInfoRegisterDTO userInfoRegisterDTO) {
        if(ObjectUtil.isEmpty(userInfoRegisterDTO)){
            throw new MyException(MyExceptionEnum.OBJECT_IS_NULL);
        }

        //查看该用户号是否被使用
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper
                .lambda()
                .eq(User::getUserNo,userInfoRegisterDTO.getUserNo());

        int userNoCount = baseMapper.selectCount(userQueryWrapper);
        if(userNoCount > 0){
            //用户号被使用
            throw new MyException(MyExceptionEnum.USER_NO_REPEATED);
        }

        userQueryWrapper.lambda().clear();

        userQueryWrapper
                .lambda()
                .eq(User::getPhone,userInfoRegisterDTO.getPhone());

        int userPhoneCount = baseMapper.selectCount(userQueryWrapper);
        if(userPhoneCount > 0){
            //用户号被使用
            throw new MyException(MyExceptionEnum.USER_PHONE_REPEATER);
        }

        User user = userMapStruct.userInfoRegisterDTOTOUser(userInfoRegisterDTO);
        //用户设置临时角色和临时部门号
        user.setRoleId(1L);
        user.setRoleName("临时角色");
        user.setDeptId(1L);
        user.setDeptName("临时部门");
        user.setPassword(MD5.encrypt(userInfoRegisterDTO.getPassword()));

        int registerCount = this.baseMapper.insert(user);

        return registerCount>0?Boolean.TRUE:Boolean.FALSE;
    }

    /**
     * 根据条件搜索用户
     * @param userQueryModelReq
     * @return
     */
    @Override
    public Map<String,Object> getUserInfoByCondition(UserQueryModelReq userQueryModelReq) {
        Map<String,Object> map = new HashMap<>();

        if(ObjectUtil.isEmpty(userQueryModelReq)){
            throw new MyException(MyExceptionEnum.OBJECT_IS_NULL);
        }

        Integer pageNum = userQueryModelReq.getPageNum();
        Integer pageSize = userQueryModelReq.getPageSize();

        String userNo = Optional.ofNullable(userQueryModelReq.getUserNo()).orElse(null);
        String realName = Optional.ofNullable(userQueryModelReq.getRealName()).orElse(null);
        String deptName = Optional.ofNullable(userQueryModelReq.getDeptName()).orElse(null);

        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper
                .lambda()
                .eq(StrUtil.isNotBlank(userNo),User::getUserNo,userNo)
                .like(StrUtil.isNotBlank(realName),User::getRealName,realName)
                .like(StrUtil.isNotBlank(deptName),User::getDeptName,deptName);


        Page<User> page = new Page<>(pageNum,pageSize);
        IPage<User> iPage = this.baseMapper.selectPage(page,userQueryWrapper);

        List<User> users = Optional.ofNullable(iPage.getRecords()).orElse(new LinkedList<>());

        map.put("total",this.baseMapper.selectCount(userQueryWrapper));
        map.put("users",users);

        return map;
    }

    /**
     * 获取用户详情
     * @param userId
     * @return
     */
    @Override
    public UserInfoDetailVO getUserDetailById(Long userId) {
        if(ObjectUtil.isEmpty(userId)){
            throw new MyException(MyExceptionEnum.ID_IS_NULL);
        }

        User user = this.baseMapper.selectById(userId);

        return userMapStruct.userToUserInfoDetailVO(user);
    }

    /**
     * 修改用户状态
     * @param userId
     * @return
     */
    @Override
    public Boolean changeUserStatus(Long userId) {
        if(ObjectUtil.isEmpty(userId)){
            throw new MyException(MyExceptionEnum.ID_IS_NULL);
        }

        User user = this.baseMapper.selectById(userId);
        Integer userStatus = user.getUserStatus();
        if(userStatus == 1){
            //启用改成禁用
            user.setUserStatus(0);
            this.baseMapper.updateById(user);
            return false;
        }else {
            //禁用改成启用
            user.setUserStatus(1);
            this.baseMapper.updateById(user);
            return true;
        }
    }

    /**
     * 修改用户信息
     * @param userInfoDTO
     */
    @Override
    @Transactional
    public void updateUserInfo(UserInfoDTO userInfoDTO) {
        if(ObjectUtil.isEmpty(userInfoDTO)){
            throw new MyException(MyExceptionEnum.OBJECT_IS_NULL);
        }

        Long userId = userInfoDTO.getUserId();

        User dbUser = this.baseMapper.selectById(userId);

        //对部门修改时，计算部门人数
        if(dbUser.getDeptId().compareTo(userInfoDTO.getDeptId()) != 0){
            Department department = departmentMapper.selectById(dbUser.getDeptId());

            //计算部门人数
            AtomicInteger count = new AtomicInteger(Optional.ofNullable(this.lambdaQuery().eq(User::getDeptId, dbUser.getDeptId()).count()).orElse(0));
            department.setCounts(Math.max(count.decrementAndGet(), 0));

            //更新人数
            departmentMapper.updateById(department);

            //对新部门人数需要累加
            Department newDepartment = departmentMapper.selectById(userInfoDTO.getDeptId());

            //计算部门人数
            AtomicInteger newCount = new AtomicInteger(Optional.ofNullable(this.lambdaQuery().eq(User::getDeptId, userInfoDTO.getDeptId()).count()).orElse(0));
            newDepartment.setCounts(newCount.incrementAndGet());
            departmentMapper.updateById(newDepartment);
        }

        //针对数据库的数据进行修改
        dbUser.setRealName(userInfoDTO.getRealName())
              .setRoleId(userInfoDTO.getRoleId())
              .setRoleName(userInfoDTO.getRoleName())
              .setDeptId(userInfoDTO.getDeptId())
              .setDeptName(userInfoDTO.getDeptName());

        Optional.ofNullable(userInfoDTO.getGender()).ifPresent(
                gender -> {
                    if(gender.equals("男")){
                        dbUser.setGender(1);
                    }else {
                        dbUser.setGender(0);
                    }
                }
        );

        //选填部分修改
        Optional.ofNullable(userInfoDTO.getPhone()).ifPresent(dbUser::setPhone);
        Optional.ofNullable(userInfoDTO.getWorkMail()).ifPresent(dbUser::setWorkMail);
        Optional.ofNullable(userInfoDTO.getHeadImgUrl()).ifPresent(dbUser::setHeadImgUrl);

        this.baseMapper.updateById(dbUser);
    }

    /**
     * 修改用户密码
     * @param passwordDTO
     */
    @Override
    public void updatePassword(PasswordDTO passwordDTO) {
        if(ObjectUtil.isEmpty(passwordDTO)){
            throw new MyException(MyExceptionEnum.OBJECT_IS_NULL);
        }

        String oldPassword = passwordDTO.getOldPassword();
        String newPassword = passwordDTO.getNewPassword();

        if(oldPassword.equals(newPassword)){
            throw new MyException(MyExceptionEnum.PASSWORD_EQUALS);
        }

        //不一致可以修改密码
        Long userId = passwordDTO.getUserId();

        User dbUser = this.baseMapper.selectById(userId);

        String password = dbUser.getPassword();
        if(!password.equals(MD5.encrypt(oldPassword))){
            throw new MyException(MyExceptionEnum.PASSWORD_ERROR);
        }

        //存入新密码
        dbUser.setPassword(MD5.encrypt(newPassword));
        this.baseMapper.updateById(dbUser);
    }

    /**
     * 获取所有管理员和项目经理的ID和姓名
     * @return
     */
    @Override
    public List<DictDTO> getAllManagers() {
        QueryWrapper<Role> roleQueryWrapper = new QueryWrapper<>();
        roleQueryWrapper
                .lambda()
                .like(Role::getRoleName,"管理")
                .or()
                .like(Role::getRoleName,"项目经理");

        List<DictDTO> dictDTOList = new LinkedList<>();
        Optional.ofNullable(roleMapper.selectList(roleQueryWrapper)).ifPresent(
            roles -> {
                List<Long> roleIds = roles.stream().map(Role::getRoleId).collect(Collectors.toList());
                QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
                userQueryWrapper
                        .lambda()
                        .in(User::getRoleId,roleIds);

                List<User> users = this.baseMapper.selectList(userQueryWrapper);
                users.forEach(
                        user -> {
                            dictDTOList.add(new DictDTO(String.valueOf(user.getUserId()),user.getRealName()));
                        }
                );
            }
        );

        return dictDTOList;
    }

}




